/**
 * 作者：Sunshine_Lin
 * 链接：https://juejin.cn/post/6994594642280857630
 * 学习如何手写一个Promise类
*/
export default class Promise {
  //传入的是一个函数，这里的executor是一个函数，因为平时的写法
  /**
   * 平时使用Promise的写法
   * let promise = new Promise((resolve,reject)=>{});
   */
  constructor(executor) {
    /**
     * 解释：
     * 1、 state 是Promise的状态，分别有 pending fulfilled rejected，还没处理，初始状态为 pending
     * 2、 value是传进来的值，成功的时候，成功接受的参数
     * 3、 reason 是失败传进来的参数
     */
    this.state = "pending";
    this.value = undefined;
    this.reason = undefined;
    // 成功存放的数组
    this.onResolvedCallbacks = [];
    // 失败存放法数组
    this.onRejectedCallbacks = [];

    // 修改状态
    /**
     * 为什么要判断？
     * 因为 只能修改一次状态，只要不是pending的，就能修改
     * 修改了就不是pending了，就不能修改了
     */
    let resolve = (value) => {
      if (this.state == "pending") {
        this.state = "fulfilled";
        this.value = value;
      }
    }
    let reject = (reason) => {
      if (this.state === 'pending') {
        this.state = 'rejected';
        this.reason = reason;
      }
    }
    /**
     * 我的理解是
     * 在截取使用该Promise的用户，throws出错误的时候，我们捕获
     * 把throws的情况当作reject(错误)的情况去处理
     */
    try {
      executor(resolve, reject);
    } catch (err) {
      reject(err);
    }
  }
  // 定义.then方法
  then(onFulfilled, onRejected) {
    // 状态为fulfilled，执行onFulfilled，传入成功的值
    if (this.state === 'fulfilled') {
      onFulfilled(this.value);
    };
    // 状态为rejected，执行onRejected，传入失败的原因
    if (this.state === 'rejected') {
      onRejected(this.reason);
    };

    /**
     * 这里为什么要把把函数打入数组呢？
     * 因为当resolve在setTomeout内执行，
     * then时state还是pending等待状态，
     * 我们就需要在then调用的时候，
     * 将成功和失败存到各自的数组，
     * 一旦reject或者resolve，就调用它们。
     */
    // 当状态state为pending时
    // if (this.state === 'pending') {
    //   // onFulfilled传入到成功数组
    //   this.onResolvedCallbacks.push(() => {
    //     onFulfilled(this.value);
    //   })
    //   // onRejected传入到失败数组
    //   this.onRejectedCallbacks.push(() => {
    //     onRejected(this.reason);
    //   })
    // }
  }
}